package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class IssueController
{

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def springSecurityService
    def exportService

    def index(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def issueList = Issue.findAll("from Issue where user.username = '${username}' order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Issue.executeQuery("select count(id) from Issue where user.username = '${username}'")

        respond issueList, model: [issueCount: count[0], params: params]
    }

    def show(Issue issue)
    {
        def attachmentList = Attachment.findAll("from Attachment where issue.id = ?", [issue.id])
        def appointmentList = Activity.findAll("from Activity where issue.id = ? and type.id = ?", [issue.id, ActivityType.find("from ActivityType where name = 'Appointment'")?.id])
        def taskList = Activity.findAll("from Activity where issue.id = ? and type.id = ?", [issue.id, ActivityType.find("from ActivityType where name = 'Task'")?.id])
        def teamList = IssueTeam.findAll("from IssueTeam where issue.id = ?", [issue.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where issue.id = ?", [issue.id])

        respond issue, model: [attachmentList: attachmentList, appointmentList: appointmentList, taskList: taskList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, teamName: 'issueTeam']
    }

    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new Issue(params), model: [user: user]
    }

    @Transactional
    def save(Issue issue)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (issue == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (issue.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond issue.errors, model: [user: user], view: 'create'
            return
        }

        issue.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'issue.label', default: 'Issue'), issue.id])
                redirect issue
            }
            '*' { respond issue, [status: CREATED] }
        }
    }

    def edit(Issue issue)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond issue, model: [user: user]
    }

    @Transactional
    def update(Issue issue)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (issue == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (issue.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond issue.errors, model: [user: user], view: 'edit'
            return
        }

        issue.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'issue.label', default: 'Issue'), issue.id])
                redirect issue
            }
            '*' { respond issue, [status: OK] }
        }
    }

    @Transactional
    def delete(Issue issue)
    {

        if (issue == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        issue.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'issue.label', default: 'Issue'), issue.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'issue.label', default: 'Issue'), params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    def searchIssue()
    {
        def username = springSecurityService?.getPrincipal()?.username
        String subject = params["subject"]

        String sql = "from Issue where user.username = '${username}'"
        if (subject)
        {
            sql += " and subject like '%${subject}%'"
        }
        String countSql = "select count(id) " + sql
        sql += " order by modifiedDate desc"

        def list = Issue.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Issue.executeQuery(countSql)

        respond list, model: [issueCount: count[0], params: params], view: 'index'
    }

    def exportIssue()
    {
        def username = springSecurityService?.getPrincipal()?.username
        String subject = params["subject"]

        String sql = "from Issue where user.username = '${username}'"
        if (subject)
        {
            sql += " and subject like '%${subject}%'"
        }
        String countSql = "select count(id) " + sql
        sql += " order by modifiedDate desc"

        def list = Issue.findAll(sql)
        def count = Issue.executeQuery(countSql)

        if (params?.f && params.f != "html")
        {
            response.contentType = grailsApplication.config.grails.mime.types[params.f]
            response.setHeader("Content-disposition", "attachment; filename=issue.${params.extension}")
            List fields = ["contact.fullName", "account.name", "asset.name", "subject", "status.name", "origin.name", "priority.name", "type.name", "reason.name", "description", "createdDate", "modifiedDate"]
            Map labels = ["contact.fullName": "联系人", "account.name": "客户", "asset.name": "资产", "subject": "标题", "status.name": "状态", "origin.name": "来源", "priority.name": "优先级", "type.name": "类型", "reason.name": "原因", "description": "详细说明", "createdDate": "创建时间", "modifiedDate": "修改时间"]
            exportService.export(params.f, response.outputStream, list, fields, labels, [:], [:])
        }
    }
}
